mod cmd;
mod interpreter;
mod classpath;
mod classfile;
mod rtda;
mod instructions;
mod native;
#[allow(warnings)]
mod JVM;

mod test;

use std::sync::mpsc::{channel, Sender};
use JVM::JVM as Jvm;

use cmd::Cmd;
use native::THREADS;
use once_cell::sync::Lazy;


pub(crate) type SenderType = Result<(), ()>;

// 嵌套结构体为Sender实现Sync trait
pub struct MainSender {
    inner: Option<Sender<()>>
}

unsafe impl Sync for MainSender {}

impl MainSender {
    pub fn new() -> MainSender {
        MainSender{ inner: None }
    }

    pub fn set_sender(&mut self, sender: Sender<()>) {
        self.inner = Some(sender);
    }

    pub fn take_sender(&mut self) -> Option<Sender<()>> {
        self.inner.take()
    }

    pub fn clone_sender(&self) -> Option<Sender<()>> {
        self.inner.clone()
    }
}

// 存储java mian线程的Sender,用于创建线程.
pub static mut MIAN_SENDER: Lazy<MainSender> = Lazy::new(|| MainSender::new());





// cargo run -- -Xjre /home/lixun/jdk1.8.0_381/jre -cp /home/lixun/Code/jvm-rust/java -verbose:inst HelloWorld
// cargo run -- -Xjre /Library/Java/JavaVirtualMachines/jdk1.8.0_361.jdk/Contents/Home/jre -cp /Users/lixun/Code/jvm-rust/java HelloWorld
fn main() {
    let cmd = Cmd::parse_cmd();

    if cmd.version_flag {
        println!("version 0.1");
    } else if cmd.help_flag || cmd.class.is_empty() {
        Cmd::print_usage();
    } else {
        jvm_run(cmd);
    }
}

// java线程实现思路：rust主线程创建java主线程，java主线程持有rust主线程sender，rust主线程等待java主线程结束。
// java主线程持有自身的sender用于常见线程，创建的非守护线程都持有此sender，java主线程等待其创建的所有非守护线程结束。
pub fn jvm_run(cmd: Cmd) {
    // rust主线程sender,由JVM持有
    let (sender, receiver) = channel();
    let mut jvm = Jvm::new_jvm(cmd, sender);
    let main_thread = jvm.main_thread();
    let key = main_thread.lock().unwrap().get_j_thread().unwrap() as usize;
    let thread_handle = std::thread::Builder::new().name("main".to_string()).spawn(move || {

        // java main线程 sender 由java main线程持有
        let (main_sender, main_receiver) = channel();
        main_thread.lock().unwrap().set_sender(main_sender);

        // 执行main方法
        jvm.start();

        // 执行完成后释放main线程sender
        let main_sender = main_thread.lock().unwrap().take_sender();
        if let Some(sender) = main_sender {
            drop(sender); // 手动结束sender生命周期
        }

        // 等待其他线程结束
        for _ in main_receiver { }

        // 其他线程执行完成后释放rust主线程sender
        let sender = jvm.take_sender();
        if let Some(sender) = sender {
            drop(sender); // 手动结束sender生命周期
        }

        // 线程结束
        THREADS.lock().unwrap().remove(&key);
    });
    THREADS.lock().unwrap().insert(key, thread_handle.unwrap());
    // 等待其他线程结束
    for _ in receiver { }
}
